/*
 * $Id: AppController.java 129 2009-07-09 06:25:26Z donbeave $
 */

package labour.manager.client.mvc;

import labour.concept.client.data.json.JsonObjectsReader;
import labour.concept.engine.client.data.EngineManager;
import labour.concept.engine.client.data.EngineObjectModel;
import labour.concept.engine.client.data.EngineObjectModelType;
import labour.concept.engine.client.data.json.JsonEngineConnector;
import labour.manager.client.AppEvents;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class AppController extends Controller {

  public static String MANAGER = "AppController.MANAGER";

  private AppView appView;

  protected AppEvent currentEvent;

  public AppController() {
    registerEventTypes(AppEvents.Init);
    registerEventTypes(AppEvents.Login);
    registerEventTypes(AppEvents.Error);
  }

  @Override
  public void initialize() {
    appView = new AppView(this);
  }

  public void handleEvent(AppEvent event) {
    currentEvent = event;

    EventType type = event.getType();

    if (type == AppEvents.Init) {
      onInit();
    }
    else if (type == AppEvents.Login) {
      forwardToView(appView, event);
    }
    else if (type == AppEvents.Error) {
      onError(event);
    }
  }

  protected void onInit() {
    JsonEngineConnector connector = new JsonEngineConnector("/instances/engine/");
    connector.getObjectsReader().setObjectsReader(new JsonObjectsReader<EngineObjectModel>(new EngineObjectModelType()) {
      @Override
      protected ModelData newModelInstance() {
        return new EngineObjectModel();
      }
    });

    EngineManager manager = new EngineManager(connector);

    Registry.register(MANAGER, manager);

    manager.initialize(new AsyncCallback<Object>() {
      public void onFailure(Throwable caught) {
        AppEvent event = new AppEvent(AppEvents.Error);
        event.setData(caught);

        Dispatcher.forwardEvent(event);
      }

      public void onSuccess(Object result) {
        forwardToView(appView, currentEvent);

        Dispatcher.forwardEvent(AppEvents.Ready);
      }
    });
  }

  protected void onError(AppEvent event) {
    if (event.getData() instanceof Throwable) {
      Throwable caught = (Throwable) event.getData();

      caught.printStackTrace();

      MessageBox.alert("Error", caught.getMessage(), null);
    }
  }

}
